package controllers

import (
	"net/http"
	"obsidian-plugin-server/config"
	"obsidian-plugin-server/models"
	"obsidian-plugin-server/utils"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type AuthController struct {
	DB        *gorm.DB
	JWTConfig *config.JWTConfig
}

// RegisterRequest 注册请求
type RegisterRequest struct {
	Name     string `json:"name" binding:"required,min=3,max=50"`
	Password string `json:"password" binding:"required,min=6"`
}

// LoginRequest 登录请求
type LoginRequest struct {
	Name     string `json:"name" binding:"required"`
	Password string `json:"password" binding:"required"`
}

// Register 用户注册
func (ac *AuthController) Register(c *gin.Context) {
	var req RegisterRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"error":   "Validation failed",
			"errors":  err.Error(),
		})
		return
	}

	// 检查用户名是否已存在
	var existingUser models.User
	if err := ac.DB.Where("name = ?", req.Name).First(&existingUser).Error; err == nil {
		c.JSON(http.StatusConflict, gin.H{
			"success": false,
			"message": "用户名已存在",
		})
		return
	}

	// 创建用户
	user := models.User{
		Name: req.Name,
	}

	if err := user.HashPassword(req.Password); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "创建用户失败: " + err.Error(),
		})
		return
	}

	if err := ac.DB.Create(&user).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "创建用户失败: " + err.Error(),
		})
		return
	}

	// 生成 API Token
	token, err := utils.GenerateApiToken(&user, ac.JWTConfig)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "生成 Token 失败: " + err.Error(),
		})
		return
	}

	// 记录 Token 日志
	tokenLog := models.Log(user.ID, "generated", token[:16], c.ClientIP(), c.Request.UserAgent(), nil)
	ac.DB.Create(tokenLog)

	c.JSON(http.StatusCreated, gin.H{
		"success": true,
		"message": "API Token 生成成功!",
		"data": gin.H{
			"user": gin.H{
				"name": user.Name,
				"uid":  user.UID,
			},
			"token_name": "api-token",
			"token":      token,
			"warning":    "请妥善保存此 Token，它只会显示一次!",
		},
	})
}

// Login 用户登录
func (ac *AuthController) Login(c *gin.Context) {
	var req LoginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"success": false,
			"error":   "Validation failed",
			"errors":  err.Error(),
		})
		return
	}

	// 查找用户
	var user models.User
	if err := ac.DB.Where("name = ?", req.Name).First(&user).Error; err != nil {
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"message": "账号或密码错误",
		})
		return
	}

	// 验证密码
	if !user.CheckPassword(req.Password) {
		c.JSON(http.StatusUnauthorized, gin.H{
			"success": false,
			"message": "账号或密码错误",
		})
		return
	}

	// 生成 API Token
	token, err := utils.GenerateApiToken(&user, ac.JWTConfig)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"success": false,
			"message": "生成 Token 失败: " + err.Error(),
		})
		return
	}

	// 记录 Token 日志
	tokenLog := models.Log(user.ID, "generated", token[:16], c.ClientIP(), c.Request.UserAgent(), nil)
	ac.DB.Create(tokenLog)

	c.JSON(http.StatusOK, gin.H{
		"success": true,
		"message": "API Token 生成成功!",
		"data": gin.H{
			"user": gin.H{
				"name": user.Name,
				"uid":  user.UID,
			},
			"token_name": "api-token",
			"token":      token,
			"warning":    "请妥善保存此 Token，它只会显示一次!",
		},
	})
}
